Webhooks
This document outlines the webhook functionality in the TrustChex system.
Overview
Webhooks allow your application to receive real-time notifications about events happening in your TrustChex account. When an event occurs, we'll send a HTTP POST request to the configured webhook URL.
Key Features:
- Real-time event notifications
- Automatic retry mechanism with exponential backoff
- HMAC SHA256 signature verification for security
- Comprehensive event logging and monitoring
- Test functionality for easy debugging
Event Types
Verification Session Events
verification_session.created
- A new verification session has been createdverification_session.completed
- A verification session has been completedverification_session.cancelled
- A verification session has been cancelled
Identification Events
identification.created
- A new identification has been createdidentification.submitted
- An identification has been submitted for reviewidentification.failed
- An identification has failed processingidentification.in_automatic_review
- An identification is under automatic reviewidentification.in_manual_review
- An identification requires manual reviewidentification.waiting_for_status_change_approval
- Status change requires approvalidentification.approved
- An identification has been approvedidentification.rejected
- An identification has been rejectedidentification.resubmission_required
- An identification requires resubmission
Managing Webhooks
Creating a Webhook
- Navigate to Settings > Webhooks in your dashboard
- Click "New Webhook"
- Configure your webhook:
- URL: The endpoint where you want to receive webhook events
- Description: Optional description for your webhook
- Events: Select which event types you want to subscribe to
- Active: Enable/disable the webhook
- Click "Save" to create your webhook
Testing Webhooks
Use the test button in the webhook dashboard to verify your endpoint:
- Click the Test button next to your webhook
- A test event will be sent to your endpoint
- Check the event logs to see the delivery status
- Review the request/response details for debugging
Webhook Payload
All webhooks include the following standard fields:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"accountId": "your-account-id",
"webhookId": "webhook-id",
"eventType": "identification.approved",
"timestamp": "2024-01-01T12:00:00.000Z",
"data": {
"accountId": "your-account-id",
"identificationId": "identification-id",
"status": "APPROVED",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"score": 95,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}
Event-Specific Payload Examples
Verification Session Data Structure
{
"data": {
"accountId": "your-account-id",
"sessionId": "session-id",
"status": "COMPLETED",
"identificationId": "identification-id",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"locale": "en",
"sendOTP": true,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z",
"expiresAt": "2024-01-01T13:00:00.000Z"
}
}
Identification Data Structure
{
"data": {
"accountId": "your-account-id",
"identificationId": "identification-id",
"status": "APPROVED",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"score": 95,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}
Headers
Each webhook request includes these headers:
Content-Type: application/json
User-Agent: TrustChex-Webhook/1.0
X-Webhook-Event: {eventType}
X-Webhook-Delivery: {deliveryId}
X-Webhook-Timestamp: {timestamp}
X-Webhook-Secret: {secret}
(if configured)X-Webhook-Signature-256: sha256={signature}
(if secret configured)
Security
Secret Verification
If you configure a secret for your webhook, we'll include it in the X-Webhook-Secret
header and generate a HMAC SHA256 signature in the X-Webhook-Signature-256
header.
To verify the signature:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Delivery and Retries
- Webhooks have a 30-second timeout
- Failed deliveries are retried up to 3 times with exponential backoff (1s, 3s, 9s)
- HTTP status codes 2xx are considered successful
- All webhook attempts are logged and can be viewed in the dashboard
Testing
Use the test functionality in the webhook dashboard to send a test event to your endpoint:
{
"id": "test-delivery-id",
"accountId": "your-account-id",
"webhookId": "your-webhook-id",
"eventType": "test.webhook",
"timestamp": "2024-01-01T12:00:00.000Z",
"data": {
"message": "This is a test webhook delivery",
"test": true
}
}
Test Endpoint
For testing purposes, you can use our public webhook endpoint:
https://your-domain.com/api/public/webhooks
Query parameters:
?fail=true
- Simulate a failure (returns 500)?status=404
- Return specific status code?delay=5000
- Add delay in milliseconds (max 60000)
Best Practices
- Idempotency: Use the webhook delivery ID to avoid processing duplicate events
- Timeout Handling: Respond within 30 seconds to avoid timeouts
- Error Handling: Return appropriate HTTP status codes (2xx for success)
- Security: Always verify webhook signatures when using secrets
- Logging: Log webhook events for debugging and monitoring
- Graceful Degradation: Handle webhook failures gracefully in your application
Example Implementations
Node.js Express
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature-256'];
const secret = process.env.WEBHOOK_SECRET;
if (secret && signature) {
const payload = JSON.stringify(req.body);
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
return res.status(401).send('Unauthorized');
}
}
console.log('Webhook received:', req.body);
// Process the webhook event
switch (req.body.eventType) {
case 'identification.approved':
// Handle approval
break;
case 'identification.rejected':
// Handle rejection
break;
default:
console.log('Unknown event type:', req.body.eventType);
}
res.json({ received: true });
});
Python Flask
import hmac
import hashlib
import json
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Webhook-Signature-256')
secret = os.environ.get('WEBHOOK_SECRET')
if secret and signature:
payload = request.get_data()
expected_signature = 'sha256=' + hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected_signature):
return jsonify({'error': 'Unauthorized'}), 401
data = request.get_json()
print(f"Webhook received: {data}")
# Process the webhook event
event_type = data.get('eventType')
if event_type == 'identification.approved':
# Handle approval
pass
elif event_type == 'identification.rejected':
# Handle rejection
pass
return jsonify({'received': True})